package jp.jig.test.alarm;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.IBinder;
import android.os.Vibrator;
import android.util.Log;

import com.google.android.gcm.GCMRegistrar;

public class AlarmService extends Service {

	public static final String ACTION_STARTUP = "jp.jig.test.alarm.START_UP";
	public static final String ACTION_SEND_MESSAGE = "jp.jig.test.alarm.SEND_MESSAGE";
	public static final String ACTION_POST_RID = "jp.jig.test.alarm.POST_RID";
	public static final String ACTION_SET_ALARM = "jp.jig.test.alarm.SET_ALARM";
	public static final String ACTION_FROM_TIMER = "jp.jig.test.alarm.FROM_TIMER";
	public static final String ACTION_STOP_RING_AND_VIB = "jp.jig.test.alarm.stop_ring_and_vib";
	public static final String ACTION_TWEET = "jp.jig.test.alarm.tweet";
	public static final String ACTION_TWEET_CANCEL = "jp.jig.test.alarm.tweet_cancel";

	public static final String EXTRA_MESSAGE = "extra_message";
	public static final String EXTRA_RID = "extra_rid";
	public static final String EXTRA_ALARM_TIME = "extra_alarm_time";

	private AlarmManager mAlarmManager;

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO 自動生成されたメソッド・スタブ
		return null;
	}

	@Override
	public void onCreate() {
		// TODO 自動生成されたメソッド・スタブ
		mAlarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
		super.onCreate();

	}

	@Override
	public void onDestroy() {
		// TODO 自動生成されたメソッド・スタブ
		super.onDestroy();
	}

	public static void startService(Context context) {
		Intent service = new Intent(context, AlarmService.class);
		service.setAction(ACTION_STARTUP);
		context.startService(service);
	}

	public static void sendMessage(Context context, String message) {
		Intent service = new Intent(context, AlarmService.class);
		service.setAction(ACTION_SEND_MESSAGE);
		service.putExtra(EXTRA_MESSAGE, message);
		context.startService(service);
	}

	public static void postRID(Context context, String rid) {
		Intent service = new Intent(context, AlarmService.class);
		service.setAction(ACTION_POST_RID);
		service.putExtra(EXTRA_RID, rid);
		context.startService(service);
	}

	public static void setAlarm(Context context, long time) {
		Intent service = new Intent(context, AlarmService.class);
		service.setAction(ACTION_SET_ALARM);
		service.putExtra(EXTRA_ALARM_TIME, time);
		context.startService(service);
	}

	public static void stopTweetTimer(Context context) {
		Intent service = new Intent(context, AlarmService.class);
		service.setAction(ACTION_TWEET_CANCEL);
		context.startService(service);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		if (intent != null) {
			String action = intent.getAction();
			if (action != null) {
				if (action.equals(ACTION_STARTUP)) {
					startGCMRegister();
				} else if (action.equals(ACTION_SEND_MESSAGE)) {
					String message = intent.getStringExtra(EXTRA_MESSAGE);
					try {
						message = URLDecoder.decode(message, "UTF-8");
					} catch (Throwable e) {
					}
					sendNotice(message);
				} else if (action.equals(ACTION_POST_RID)) {
					String rid = intent.getStringExtra(EXTRA_RID);
					sendRID(rid);
				} else if (action.equals(ACTION_SET_ALARM)) {
					long time = intent.getLongExtra(EXTRA_ALARM_TIME, 0);
					if (time != 0) {
						// タイマーをセットする
						setAlarm(time);
					}
				} else if (action.equals(ACTION_FROM_TIMER)) {
					Intent intent2 = new Intent(this, WakeUpActivity.class);
					intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
					this.startActivity(intent2);
					startRingAndVibration();
					setTweetTimer();
				} else if (action.equals(ACTION_STOP_RING_AND_VIB)) {
					stopRingAndVibration();
				} else if (action.equals(ACTION_TWEET)) {
					tweet(false);
				} else if (action.equals(ACTION_TWEET_CANCEL)) {
					cancelTweetTimer();
				}
			}
		}

		return super.onStartCommand(intent, flags, startId);
	}

	private boolean startGCMRegister() {
		GCMRegistrar.checkDevice(this);
		GCMRegistrar.checkManifest(this);
		final String regId = GCMRegistrar.getRegistrationId(this);
		if (regId.equals("")) {
			GCMRegistrar.register(this, SENDER_ID);
			return true;
		} else {
			Log.v(this.getClass().getName(), "Already registered");
			sendRID(regId);
			return false;
		}
	}


	public static final String SENDER_ID = "991332016232";
	public static final String SERVER_URL = "http://u1fukui.com:8080/alarm/registration";

	private void sendRID(String id) {

		final String rid = id;
		final String userName = "u1_tokyo";
		final Context context = this;

		Runnable r = new Runnable() {
			@Override
			public void run() {
				// -----[クライアント設定]
				HttpClient httpclient = new DefaultHttpClient();
				HttpPost httppost = new HttpPost(SERVER_URL);

				// -----[POST送信するデータを格納]
				List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(1);
				nameValuePair.add(new BasicNameValuePair("user", userName));
				nameValuePair.add(new BasicNameValuePair("rid", rid));

				try {
					// -----[POST送信]
					httppost.setEntity(new UrlEncodedFormEntity(nameValuePair));
					HttpResponse response = httpclient.execute(httppost);
					ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
					response.getEntity().writeTo(byteArrayOutputStream);

					// -----[サーバーからの応答を取得]
					if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
						System.out.println("[プッシュ用ID　POST完了]: " + response.getStatusLine());
					} else {
						System.out.println("[プッシュ用ID　POST失敗]: " + response.getStatusLine());
					}
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		};

		Thread t = new Thread(r);
		t.start();

		//		tweet();
	}

	private static final int TIMER_REQUEST_CODE = 1;
	private void setAlarm(long time) {
		// インテント作成
		Context context = getBaseContext();
		Intent intent = new Intent(context, AlarmService.class);
		intent.setAction(ACTION_FROM_TIMER);
		PendingIntent pi = PendingIntent.getService(context, TIMER_REQUEST_CODE, intent, PendingIntent.FLAG_CANCEL_CURRENT);
		// アラームセット
		mAlarmManager.set(AlarmManager.RTC_WAKEUP, time, pi);
	}

	private static final int TWEET_REQUEST_CODE = 2;

	// 15秒後に起こしてツイート
	private void setTweetTimer() {
		// インテント作成
		Context context = getBaseContext();
		Intent intent = new Intent(context, AlarmService.class);
		intent.setAction(ACTION_TWEET);
		PendingIntent pi = PendingIntent.getService(context, TWEET_REQUEST_CODE, intent, PendingIntent.FLAG_CANCEL_CURRENT);
		// アラームセット
		mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (15 * 1000), pi);
	}

	// 起こしてツイートキャンセル
	private void cancelTweetTimer() {
		// インテント作成
		Context context = getBaseContext();
		Intent intent = new Intent(context, AlarmService.class);
		intent.setAction(ACTION_TWEET);
		PendingIntent pi = PendingIntent.getService(context, TWEET_REQUEST_CODE, intent, PendingIntent.FLAG_CANCEL_CURRENT);
		// アラームキャンセル
		mAlarmManager.cancel(pi);
		// 起きましたツイート
		tweet(true);
		GCMRegistrar.unregister(context);// プッシュ通知解除
		sendRID("");
		stopSelf();
	}

	public static void tweet(final boolean isWakeuped) {
		AsyncTask<String, String, String> task = new AsyncTask<String, String, String>(){

			@Override
			protected String doInBackground(String... params) {

				try{
					String token = "";// load from a persistent store
					String tokenSecret = "";// load from a persistent store
					String consumer = "";
					String consumerSecret = "";
					AccessToken accessToken = new AccessToken(token, tokenSecret);

					TwitterFactory factory = new TwitterFactory();
					Twitter twitter = factory.getInstance();
					twitter.setOAuthConsumer(consumer, consumerSecret);

					twitter.setOAuthAccessToken(accessToken);

					Calendar cal = Calendar.getInstance();
					StringBuffer sb = new StringBuffer();
					sb.append(cal.get(Calendar.MONTH)).append("月").append(cal.get(Calendar.DATE)).append("日 ").append(cal.get(Calendar.HOUR_OF_DAY)).append(":").append(cal.get(Calendar.MINUTE));

					if (!isWakeuped) {
						twitter4j.Status status = twitter.updateStatus("u1_tokyoが寝坊しています…。ボタンを押して僕を起こしてやって下さい！ " + sb.toString() + " http://u1fukui.com:8080/alarm/?user=u1_tokyo");
					} else {
						twitter4j.Status status = twitter.updateStatus("起きました!! " + sb.toString());
					}
				}catch (Exception e) {
					e.printStackTrace();
				}

				return null;
			}

		};
		try {
			task.execute("");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static final int NOTIFICATION_ID = 1;

	private void sendNotice(String message) {
		String statusBarTitle = "AlarmNetwork";
		String appName = getResources().getString(R.string.app_name);

		NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		Notification notice = new Notification(R.drawable.ic_launcher, statusBarTitle, System.currentTimeMillis());
		// notice.defaults = Notification.DEFAULT_ALL;
		notice.flags = Notification.FLAG_AUTO_CANCEL;

		Intent intent = new Intent(this, WakeUpActivity.class);

		PendingIntent pintent = PendingIntent.getActivity(this, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
		notice.setLatestEventInfo(this, appName, message, pintent);
		nManager.notify(NOTIFICATION_ID, notice);
		startRingAndVibration();
	}

	private Ringtone mRing = null;
	private Vibrator mVib = null;

	private void startRingAndVibration() {
		stopRingAndVibration();// mRingとmVibを初期化、リセットする(すでに動作中なら停止させる)

		Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
		mRing = RingtoneManager.getRingtone(getApplicationContext(), soundUri);
		if (mRing != null) {
			mRing.play();
		}

		mVib = (Vibrator) getSystemService(VIBRATOR_SERVICE);
		try {
			mVib.vibrate(new long[] {
					0,
					1000,
					1000,
					1000,
					1000,
					1000,
					1000,
					1000,
					1000,
					1000
			}, -1);
		} catch (Throwable e) {
		}
	}

	private void stopRingAndVibration() {
		if (mRing != null) {
			mRing.stop();
			mRing = null;
		}
		if (mVib != null) {
			mVib.cancel();
			mVib = null;
		}
	}

	/**
	 * アラーム、バイブレーションを停止させます
	 * 
	 */
	public static void sendRingAndVibrationStopCommand(Context context) {
		Intent intent = new Intent(context, AlarmService.class);
		intent.setAction(ACTION_STOP_RING_AND_VIB);
		context.startService(intent);
	}

}
